package com.fumasoft.dynamic.handler;

import com.fumasoft.bill.server.enums.ResultCode;
import com.fumasoft.bill.server.exceptions.BizException;
import com.fumasoft.bill.server.exceptions.InternalBizException;
import com.fumasoft.bill.server.vo.ResponseResult;
import javax.validation.ValidationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.ServletWebRequest;

/**
 * 全局异常处理.
 *
 * @author jingchen
 * @since 2025-08-30
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @Value("${spring.application.name}")
    private String applicationName;


    /**
     * 处理自定义业务异常.
     */
    @ExceptionHandler(value = BizException.class)
    public ResponseResult<Object> bizExceptionHandler(ServletWebRequest request, BizException e) {
        ResponseResult<Object> result = ResponseResult.failed(applicationName, e, request);
        log.info("业务异常处理 uri:{},traceId:{},traceServerMsg:{}, e:", request.getRequest().getRequestURI(), result.getTraceId(), result.getServerMsgs(), e);
        return result;
    }

    /**
     * 接收远程调用异常.
     */
    @ExceptionHandler(value = InternalBizException.class)
    public ResponseResult<Object> internalBizExceptionHandler(ServletWebRequest request, InternalBizException e) {
        ResponseResult<Object> result = ResponseResult.failed(applicationName, e, request);
        log.error("接收远程调用异常处理 uri:{},traceId:{},traceServerMsg:{}, e:", request.getRequest().getRequestURI(), result.getTraceId(), result.getServerMsgs(), e);
        return result;
    }

    /**
     * 参数校验异常.
     */
    @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
    public ResponseResult<String> handleBindException(ServletWebRequest request, BindException e) {
        ResponseResult<String> result = ResponseResult.failedWithParams(applicationName, ResultCode.DATA_VALID_ERROR, e, request);
        log.error("业务校验异常处理 uri:{},traceId:{},traceServerMsg:{}, e:", request.getRequest().getRequestURI(), result.getTraceId(), result.getServerMsgs(), e);
        return result;
    }

    /**
     * 处理其它异常.
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseResult<String> exceptionHandler(ServletWebRequest request, Exception e) {
        ResponseResult<String> result = ResponseResult.failed(applicationName, ResultCode.SYSTEM_ERROR, e, request);
        log.error("系统异常处理 uri:{},traceId:{},traceServerMsg:{}, e:", request.getRequest().getRequestURI(), result.getTraceId(), result.getServerMsgs(), e);
        return result;
    }

}
